/**
 * Unix socket 通过本地创建一个sock文件的形式，让多个客户端连接实现本地机器多个进程之间的
 * 通信。
 * 用法和普通IP协议的Socket用法是差不多的。
 */
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>

#include <iostream>

int main() {
    using namespace std;
    char buffer[255];
    struct sockaddr_un socketAddress;
    string socketFile("/tmp/test_unix_socket_3271846.sock"); // 这里路径长度不能大于107字节

    auto socketId = socket(AF_UNIX, SOCK_STREAM, 0);
    if (-1 == socketId) {
        cout << "Call socket fail, function return " << socketId << endl;
        return 1;
    }

    socketAddress.sun_family = AF_UNIX;
    socketAddress.sun_path[socketFile.length()] = '\0';
    socketFile.copy(socketAddress.sun_path, socketFile.length());

    if (0 != connect(socketId, (sockaddr *)&socketAddress, sizeof(socketAddress))) {
        cout << "Call connect fail" << endl;
        return 1;
    }

    cout << "Send: Hello, I am client." << endl;
    string sendMessage("Hello, I am client.");
    auto sendDataLength = send(socketId, sendMessage.c_str(), sendMessage.length(), 0);
    if (sendMessage.length() != sendDataLength) {
        cout << "Error, data not sent completely" << endl;
        close(socketId);
        return 1;
    }

    auto recvDataLength = recv(socketId, buffer, 254, 0);
    if (recvDataLength <= 0) {
        cout << "Error, received data with length of 0 bytes" << endl;
        close(socketId);
        return 1;
    }

    buffer[recvDataLength] = '\0';
    cout << buffer << endl;

    close(socketId);
    return 0;
}

